package com.onstar.cn.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.onstar.cn.common.bean.BaseObject;

public final class XMLUtil {

	public static String toXml(Object object) {
		Map<String, Object> map = toMap(object);
		return generatetoXml(map);
	}

	public static Map<String, Object> toMap(Object entity) {
		Map<String, Object> map = new HashMap<String, Object>();
//		Class<?> clazz = entity.getClass();
//		Field[] fields = clazz.getDeclaredFields();
//		for (Field field : fields) {
//			try {
//				Method method = clazz.getMethod("get" + upperFirstWord(field.getName()));
//				Object obj = method.invoke(entity);
//				if (obj != null) {
//					if (obj instanceof Enum) {
//						map.put(field.getName(), obj);
//					} else if (!isBaseObject(obj.getClass())) {
//						Map<String, Object> childMap = toMap(obj);
//						map.put(field.getName(), childMap);
//					} else {
//						map.put(field.getName(), obj);
//					}
//				}
//			} catch (NoSuchMethodException e) {
//				e.printStackTrace();
//			} catch (IllegalAccessException e) {
//				e.printStackTrace();
//			} catch (IllegalArgumentException e) {
//				e.printStackTrace();
//			} catch (InvocationTargetException e) {
//				e.printStackTrace();
//			}
//		}
		return map;
	}

	private static String upperFirstWord(String words) {
		if (words != null && words.length() != 0) {
			String newWords = words;
			String first = words.substring(0, 1).toUpperCase(Locale.CHINA);
			newWords = first + words.substring(1);
			return newWords;
		}
		return words.toUpperCase(Locale.CHINA);
	}

	private static boolean isBaseObject(Class<?> clazz) {
		return clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class)
				|| clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class)
				|| clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class)
				|| clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class)
				|| clazz.isPrimitive();
	}

	public static String generatetoXml(Map<String, Object> obj) {
		StringBuilder sb = new StringBuilder();
		String root = (String) obj.get("root");
		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
		sb.append("<" + root + ">\n");
		if (obj.get("xmlns") != null && !"".equals(obj.get("xmlns"))) {
			sb.append(" xmlns=\"" + obj.get("xmlns") + "\">\n");
		}
		obj.remove("root");
		obj.remove("xmlns");
		sb.append(mapToXml(obj));
		sb.append("</" + root + ">");
		return sb.toString();
	}

	@SuppressWarnings("unchecked")
	public static String mapToXml(Map<String, Object> obj) {
		StringBuilder sb = new StringBuilder();
//		Set<Entry<String, Object>> set = obj.entrySet();
//		Iterator<Entry<String, Object>> it = set.iterator();
//		while (it.hasNext()) {
//			Entry<String, Object> entry = (Entry<String, Object>) it.next();
//			if (entry.getValue() instanceof Map) {
//				Map<String, Object> childMap = (Map<String, Object>) entry.getValue();
//				sb.append("<" + entry.getKey() + ">\n");
//				sb.append(mapToXml(childMap));
//				sb.append("</" + entry.getKey() + ">\n");
//			} else {
//				if (entry.getValue() instanceof List) {
//					for (Object object : (List<Object>) entry.getValue()) {
//						sb.append("<" + entry.getKey() + ">" + object + "</" + entry.getKey() + ">\n");
//					}
//				} else {
//					sb.append("<" + entry.getKey() + ">" + entry.getValue() + "</" + entry.getKey() + ">\n");
//				}
//			}
//		}
		return sb.toString();
	}

	public static BaseObject packXMLtoMultiBaseObjects(String targetPackageName, String xml) {
		BaseObject baseObject = new BaseObject();
//		try {
//			Element root = DocumentHelper.parseText(xml).getRootElement();
//			Class<BaseObject> clazz = (Class<BaseObject>) Class.forName(targetPackageName + "."
//					+ initcap(root.getName()));
//			baseObject = clazz.newInstance();
//			Field[] fields = baseObject.getClass().getDeclaredFields();
//			List<String> listFieldNames = new ArrayList<String>();
//			for (Field field : fields) {
//				field.setAccessible(true);
//				if (field.getType().toString().contains("java.util.List")) {
//					listFieldNames.add(field.getName().replace("Lst", ""));
//				}
//			}
//			Map<String, ArrayList<BaseObject>> map = new HashMap<String, ArrayList<BaseObject>>();
//			for (Element element : (List<Element>) root.elements()) {
//				Iterator<Element> it = element.elements().iterator();
//				if (it.hasNext()) {// 是个对象
//					String setMethodName = "set" + initcap(element.getName());
//					BaseObject childBaseObject = packXMLtoMultiBaseObjects(targetPackageName, element.asXML());
//					if (listFieldNames.contains(element.getName())) {
//						setMethodName = "set" + initcap(element.getName()) + "Lst";
//
//						ArrayList<BaseObject> list = new ArrayList<BaseObject>();
//						if (!map.isEmpty() && map.get(element.getName()) != null) {
//							list = map.get(element.getName());
//						}
//						list.add(childBaseObject);
//						map.put(element.getName(), list);
//						if (isContainsMethod(baseObject.getClass(), setMethodName)) {
//							Method m1 = baseObject.getClass().getMethod(setMethodName, List.class);
//							m1.invoke(baseObject, map.get(element.getName()));
//						}
//					} else {
//						if (isContainsMethod(baseObject.getClass(), setMethodName)) {
//							Method m = baseObject.getClass().getMethod(setMethodName, childBaseObject.getClass());
//							m.invoke(baseObject, childBaseObject);
//						}
//					}
//				} else {
//					String setMethodName = "set" + initcap(element.getName());
//					if (isContainsMethod(baseObject.getClass(), setMethodName)) {
//						Method m = baseObject.getClass().getMethod(setMethodName, String.class);
//						m.invoke(baseObject, element.getText());
//					}
//				}
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
		return baseObject;
	}

	public static String initcap(String str) {
		char[] ch = str.toCharArray();
		if (ch[0] >= 'a' && ch[0] <= 'z') {
			ch[0] = (char) (ch[0] - 32);
		}
		return new String(ch);
	}

	public static boolean isContainsMethod(Class<?> clazz, String methodName) {
		Method[] methods = clazz.getMethods();
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				return true;
			}
		}
		return false;
	}
}
